package com.pxmeta.app.controller.business;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.pxmeta.common.core.domain.AjaxResult;
import com.pxmeta.common.utils.SecurityUtils;
import com.pxmeta.common.utils.wechat.WxPayCallbackUtil;
import com.pxmeta.order.dto.CreateOrderDTO;
import com.pxmeta.order.dto.VerifyReceiptDTO;
import com.pxmeta.order.entity.Order;
import com.pxmeta.order.service.IOrderService;
import com.pxmeta.order.vo.AlipayCreateOrderVO;
import com.pxmeta.order.vo.CreateOrderVO;
import com.pxmeta.user.entity.User;
import com.pxmeta.user.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.Map;

@Api(value = "订单模块", tags = "订单模块")
@RestController
@RequestMapping("/order")
@Slf4j
@CrossOrigin
public class OrderController {

    @Autowired
    private IOrderService orderService;

    @Autowired
    private IUserService userService;

    @Value("${wx.public.appId}")
    private String publicAppId;

    @Value("${wx.public.secret}")
    private String publicSecret;

    @Value("${wx.pay.apiV3key}")
    private String apiV3key;

    public static final String APP_STORE_VERIFY_RECEIPT = "https://buy.itunes.apple.com/verifyReceipt";

    private static final String APP_STORE_SANDBOX_VERIFY_RECEIPT = "https://sandbox.itunes.apple.com/verifyReceipt";

    /**
     * 碰心单商品交易结构，只有商品、订单，无SKU、超卖、购物车等场景。
     *
     * @param dto
     * @return
     */
    @ApiOperation("创建订单")
    @PostMapping("/createOrder")
    public AjaxResult<CreateOrderVO> createOrder(@RequestBody CreateOrderDTO dto) {
        Long userId = SecurityUtils.getUserId();
        Long productId = dto.getProductId(); //商品id
        CreateOrderVO vo = orderService.createOrder(userId, productId, dto.getAppStoreProductId(), 1);
        return AjaxResult.success(vo);
    }


    /**
     * 碰心单商品交易结构，只有商品、订单，无SKU、超卖、购物车等场景。
     *
     * @param dto
     * @return
     */
    @ApiOperation("支付宝创建订单")
    @PostMapping("/createOrderByAlipay")
    public AjaxResult<AlipayCreateOrderVO> createOrderByAlipay(@RequestBody CreateOrderDTO dto) {
        Long userId = SecurityUtils.getUserId();
        Long productId = dto.getProductId(); //商品id
        AlipayCreateOrderVO vo = orderService.createOrderByAlipay(userId, productId);
        return AjaxResult.success(vo);
    }


    /**
     * 碰心单商品交易结构，只有商品、订单，无SKU、超卖、购物车等场景。
     *
     * @param dto
     * @return
     */
    @ApiOperation("根据用户名下单碰心币")
    @PostMapping("/createOrderByUsername")
    public AjaxResult<CreateOrderVO> createOrderByUsername(@RequestBody CreateOrderDTO dto) {
        Long productId = dto.getProductId(); //商品id
//        User user = userService.getByUsername(dto.getUsername());
        User user = userService.getByAccount(dto.getUsername());
        CreateOrderVO vo = null;
        if (productId!=null){
            vo = orderService.createOrder(user.getId(), productId, dto.getAppStoreProductId(),dto.getOpenId());
        }else {
            vo = orderService.createOrder(user.getId(), dto.getNumber(), dto.getOpenId());
        }
        return AjaxResult.success(vo);
    }

    @GetMapping("/getOrderInfoByOrderId")
    public AjaxResult getOrderInfoByOrderId(@RequestParam Long orderId){
        Order order = orderService.getById(orderId);
        return AjaxResult.success(order);
    }


    @GetMapping("/convertTokenByCode")
    @ApiOperation("通过code换token")
    public AjaxResult convertTokenByCode(@RequestParam String code){
        String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",publicAppId,publicSecret,code);
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSONObject.parseObject(result);
        return AjaxResult.success(jsonObject);
    }


    @ApiOperation("支付回调")
    @PostMapping("/alipayNotify")
    public Response alipayNotify(@RequestParam Map<String,Object> params) {
        try {
            log.info("支付宝支付回调成功...回调结果：{}", params.toString());
            String tradeStatus = params.get("trade_status").toString();
            //支付成功处理
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)){
                String orderNo = params.get("out_trade_no").toString();
                orderService.paySuccess(orderNo, null,null,"alipay");
            }
            return Response.status(200).build();
        } catch (Exception e) {
            HashMap<String, Object> result = Maps.newHashMap();
            result.put("code", "FAIL");
            result.put("message", e.getMessage());
            return Response.status(500).entity(result).build();
        }
    }


    @ApiOperation("支付回调")
    @PostMapping("/notify")
    public Response payNotify(@RequestBody JSONObject body) {
        try {
            log.info("支付回调成功...回调结果：{}", body.toJSONString());
            String str = WxPayCallbackUtil.decryptFromResource(body, apiV3key);
            JSONObject jsonObject = JSONObject.parseObject(str);
            log.info("支付结果解密...解密结果：{}", jsonObject.toJSONString());
            //支付成功处理
            if ("SUCCESS".equals(jsonObject.getString("trade_state"))){
                String orderNo = jsonObject.getString("out_trade_no");
                orderService.paySuccess(orderNo, null,null,"wxPay");
            }
            return Response.status(200).build();
        } catch (Exception e) {
            HashMap<String, Object> result = Maps.newHashMap();
            result.put("code", "FAIL");
            result.put("message", e.getMessage());
            return Response.status(500).entity(result).build();
        }
    }

    @ApiOperation("AppStore 验证交易")
    @PostMapping("/verifyReceipt")
    public AjaxResult verifyReceipt(@RequestBody VerifyReceiptDTO dto){
        log.info("AppStore 支付回调中...回调结果：{}", JSONObject.toJSONString(dto));

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("receipt-data",dto.getReceipt());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        RestTemplate restTemplate = new RestTemplate();
        HttpEntity<JSONObject> entity = new HttpEntity<>(jsonObject,headers);
        JSONObject result = restTemplate.postForObject(APP_STORE_VERIFY_RECEIPT, entity, JSONObject.class);
        log.info("==AppStore 支付回调中...result：{}", result);
        JSONObject receipt = result.getJSONObject("receipt");

        if (receipt != null){
            String bundleId = receipt.getString("bundle_id");
            log.info("bundleId:{}",bundleId);
            if (!"com.example.pxapp".equals(bundleId)){
                return AjaxResult.error("法网恢恢疏而不漏，你的行为已被上报网警。");
            }
        }

        if (result.getInteger("status").equals(0)){
            orderService.paySuccess(dto.getOrderId(), dto.getTransactionId(),dto.getReceipt(),"appstorePay");
            return AjaxResult.success();
        }
        if (result.getInteger("status").equals(21007)){
            JSONObject sandResult = restTemplate.postForObject(APP_STORE_SANDBOX_VERIFY_RECEIPT, entity, JSONObject.class);
            if (sandResult.getInteger("status").equals(0)){
                orderService.paySuccess(dto.getOrderId(), dto.getTransactionId(),dto.getReceipt(),"appstorePay");
                return AjaxResult.success();
            }
        }

        return AjaxResult.error("验证失败");

    }



}
